#pragma once
#include <iostream>
#include <string>
#include <sys/epoll.h>
#include "Connection.hpp"

const static int gsize = 1024;

class Channel : public Connection
{
public:
    Channel(int sockfd, InetAddr &addr)
    {
        SetSockfd(sockfd);
        SetAddr(addr);
        SetEvent(EPOLLIN | EPOLLET); //  写 是常设置的
    }
    void Recver() override
    {
        while (true)
        {
            char buffer[gsize];
            ssize_t n = recv(_sockfd, buffer, sizeof(buffer), 0);
            if (n > 0)
            {
                buffer[n] = 0;
                _inbuffer += buffer;
            }
            else if (n == 0)
            {
                LOG(LogLevel::INFO) << "client quit " << _peer.ToString();
                Excepter();
                return;
            }
            else
            {
                if (errno == EAGAIN)
                {
                    break;
                }
                else if (errno == EINTR)
                {
                    continue;
                }
                else
                {
                    LOG(LogLevel::INFO) << "client recv error " << _peer.ToString();
                    Excepter();
                    break;
                }
            }
        }
        // 循环退出 ， 本轮数据读完
        // 缓存区是否有完整报文 -- 定制协议

        // 解析 回调 业务 处理
        _outbuffer += _cb(_inbuffer);

        // 读和发送
        std::cout << "_outbuffer" << _outbuffer << std::endl;
        if (!_outbuffer.empty())
            Sender();
        // 方案二
        // if (!_outbuffer.empty())
        //     Owner()->EnableReadWrite(_sockfd,true,true);
    }
    void Sender() override
    {
        while (true)
        {
            ssize_t n = send(_sockfd, _outbuffer.c_str(), _outbuffer.size(), 0);
            if (n > 0)
            {
                _outbuffer.erase(0, n);
                if (_outbuffer.size() == 0)
                    break;
            }
            else if (n == 0)
            {
                break;
            }
            else
            {
                if (errno == EAGAIN)
                    break;
                else if (errno == EINTR)
                    continue;
                else
                {
                    Excepter();
                    return;
                }
            }
        }

        // 2.缓冲区写满了
        if (!_outbuffer.empty())
        {
            // 开启对写事件的关心
            Owner()->EnableReadWrite(_sockfd, true, true);
        }
        // 1.发完了
        else
        {
            // 关闭对写事件的关心
            Owner()->EnableReadWrite(_sockfd, true, false);
        }
    }
    void Excepter() override
    {
        // 统一错误处理
        LOG(LogLevel::INFO) << "connection exception, remove " << _peer.ToString();
        if (Owner())
        {
            Owner()->DelConnection(_sockfd);
        }
    }
    ~Channel()
    {
    }
};